#include <stdio.h>
#include "mylog.h"
#include "Sharemem.hh"
#include "MessageQueue.hh"

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>       /* for signal */
#include <execinfo.h>     /* for backtrace() */

#define BACKTRACE_SIZE   16

void dump(void)
{
    int j, nptrs;
    void *buffer[BACKTRACE_SIZE];
    char **strings;

    nptrs = backtrace(buffer, BACKTRACE_SIZE);

    printf("backtrace() returned %d addresses\n", nptrs);

    strings = backtrace_symbols(buffer, nptrs);
    if (strings == NULL) {
        perror("backtrace_symbols");
        exit(EXIT_FAILURE);
    }

    for (j = 0; j < nptrs; j++)
        printf("  [%02d] %s\n", j, strings[j]);

    free(strings);
}

void signal_handler(int signo)
{

#if 0
    char buff[64] = {0x00};

    sprintf(buff,"cat /proc/%d/maps", getpid());

    system((const char*) buff);
#endif

    printf("\n=========>>>catch signal %d <<<=========\n", signo);

    printf("Dump stack start...\n");
    dump();
    printf("Dump stack end...\n");

    signal(signo, SIG_DFL); /* 恢复信号默认处理 */
    raise(signo);           /* 重新发送信号 */
}

#define INPUT_FILE "in.265"

typedef struct {
	char* DataPtr;
	int len;
}GET_PARAM;

#define MSG_DV_TYPE_MSG3 0

#define DEBUG() printf("------>%d\n", __LINE__ )
char buf[5*1024*1024] = {0}; 
char *p = buf;
char *last_p=buf;
int DVStreamGetDVData1( GET_PARAM* stamer )
{
	static FILE *fd = NULL;

	if( fd == NULL ){
		fd = fopen( INPUT_FILE, "rb");
		if( fd == NULL ){                        
			printf("open file error \n");      
			stamer->DataPtr = NULL;
			stamer->len = 0;
			return 0;                           
		}                                         

		long len = fread( buf, 1, sizeof(buf), fd );      
		printf("read date len %ld \n", len );
		//fclose( fd );          
	}

	char head[5] = { 0x00, 0x00, 0x00, 0x01};

	while(1){                     
		if( p != NULL)
			p = (char*)memmem( p, sizeof(buf) - (p-buf), head, 4);    

		if( p== NULL){
			stamer->DataPtr = NULL;
			stamer->len = 0;
			return 0;         
		}                

		if( last_p == p )
		{
			p += 1;
			continue;
		}else if( last_p[4] == 64 && 
				( p[4] == 66 ||
				  p[4] == 68 ||
				  p[4] == 2)
			){
			p += 1;
			continue;
		}
		stamer->DataPtr = last_p;
		stamer->len = (int)(p - last_p);
		last_p = p;
		p += 4;                     
		break;
	}


		return 0;
}

void writeFunc()
{
    int64_t size = 1024*1024*20;
    Sharemem memWrite = Sharemem( 1, size );
    int ret;
    
    char data[20*1024];
    FILE *fd = fopen( INPUT_FILE, "rb");
    if( fd == NULL ){                        
        printf("open file error \n");      
        return;                           
    }                                         
    long cnt = 0;
    /* while( cnt--) */
    while(1)
    {
        /* GET_PARAM stamer; */
        /* DVStreamGetDVData1( &stamer ); */
        /* if( stamer.DataPtr == NULL ) */
        /* { */
        /*     break; */
        /* } */
        int len = fread( data, 1, sizeof( data ), fd  );
        if( len <=0 )
        {
            break;
        }
        ret = memWrite.PushMedia( data, len );
        if( ret < 0 ){
            logError("\n");
        }
        usleep( 2*1000 );
        cnt++;
        logDebug("cnt %ld\n", cnt);
    }
    if( fd != NULL ){                        
        fclose(fd);
    }                                         
    sleep(5);
}

void readFunc()
{
    Sharemem memRead = Sharemem( 1, 2 ) ;

    char buf[500*1024];
    int len;
    long cnt = 0;
    while(1){
        for( int i=0; i<MAX_CHN_NUM; i++ ){
            memset( buf, 0, 128 );
#if 1
            int64_t tm_ms = 0;
            int ret = memRead.PopMedia( i, buf, len, tm_ms );
            if( ret == SHM_RMID ){
                logError("share memroy delete\n");
                exit(0);
            }else if( ret < 0 ){
                /* logDebug("chn %d read err\n"); */
                continue;
            }
            /* logDebug("time:%ld, chn %d len %d \n", tm_ms, i, len ); */
            char filename[32];
            snprintf( filename, sizeof(filename), "strame_out%d.265", i );
            FILE *fp = fopen( filename, "a" );
            if( fp != NULL )
            {
                fwrite( buf, 1, len, fp );
                fclose(fp);
            }
            if( i == 1 )
            {
                cnt++;
                logDebug("cnt %ld\n", cnt);
            }
#else
            char *p = memRead.PopMedia( 1, len );
            if( p == NULL ){
                /* logError("date is NULL...\n"); */
                continue;
            }
            logDebug("chn %d len %d date : %s\n", i, len, p );
#endif
        }
    }
}

void sendFun()
{
    MessageQueue msg = MessageQueue( 1 );

    int cnt = 100;
    MSG_DATA buf;
    while(cnt--){
        snprintf( buf.data, sizeof(buf.data), "Message Queue test.type %d,%d", cnt%10+1, cnt );
        msg.SendMesage( cnt%10+1, buf );
        usleep( 200*1000 );
    }
}

void recvFun()
{

    MessageQueue msg = MessageQueue( 1 );

    int cnt = 100;
    MSG_DATA buf;
    while(cnt--){
        msg.RecvMesage( 0, buf );
        logDebug( "data : %s\n", buf.data );
    }
}


/*Log log; */
int main( int argc, char* argv[] )
{
    signal(SIGSEGV, signal_handler);  /* 为SIGSEGV信号安装新的处理函数 */

    if( argc != 2 ){
        logError("argc != 2\n");
        exit(0);
    }

    logDebug("argv[0] %s, argv[1] %s\n", argv[0], argv[1]);

    if( strcmp( "write", argv[1] ) == 0 )
    {
        writeFunc();
    }else if( strcmp( "read", argv[1] ) == 0 ){
        readFunc();
    }else if( strcmp( "send", argv[1] ) == 0 ){
        sendFun();
    }else if( strcmp( "recv", argv[1] ) == 0 ){
        recvFun();
    }else{
        logError("argv 2 error\n");
    }

    return 0;
}

